<?php
/**
 * Copyright (c) [2019] [吴跃忠]
 * [selibra] is licensed under the Mulan PSL v1.
 * You can use this software according to the terms and conditions of the Mulan PSL v1.
 * You may obtain a copy of Mulan PSL v1 at:
 * http://license.coscl.org.cn/MulanPSL
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v1 for more details.
 */

namespace Selibra\Http\Route;


use Selibra\Config\Config;
use Selibra\Http\Lib\Request;
use Selibra\Tools\Console;

class Router
{

    /**
     * @var Request
     */
    protected Request $request;


    /**
     * @var array
     */
    protected array $routeMapper = [];


    /**
     * @return Request
     */
    public function getRequest(): Request
    {
        return $this->request;
    }


    /**
     * 设置路由
     * @param Request $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;
        return $this;
    }


    /**
     * 获取控制器命名空间
     * @return string|null
     */
    public function getControllerNamespace()
    {
        if (empty($this->routeMapper)) {
            $pathInfo = $this->request->getPathInfo();
            // 去除请求后缀
            $httpSuffix = '.' . Config::get('application.http.http_suffix');
            $pathInfoSuffix = substr($pathInfo, -mb_strlen($httpSuffix), mb_strlen($httpSuffix));
            if ($pathInfoSuffix === $httpSuffix) {
                // 去除
                $pathInfo = substr($pathInfo, 0, -mb_strlen($httpSuffix));
            }
            $routeMappers = RouterMapper::getRouterMapper($pathInfo, $this->request->getMethod());
            if (empty($routeMappers)) {
                $routeMappers = RouterMapper::getRouterMapper($pathInfo, "ANY");
            }
            if (empty($routeMappers)) {
                return null;
            }
            // 获取接口版本
            krsort($routeMappers);
            $version = $this->getRequestVersion();
            foreach ($routeMappers as $mapperVersion => $routeMapper) {
                if ($mapperVersion > $version) {
                    continue;
                }
                $this->routeMapper = $routeMapper;
                break;
            }
        }
        return !empty($this->routeMapper) ? $this->routeMapper['mapper'] : null;
    }


    /**
     * 获取当前请求版本号
     * @return array|mixed|string|null
     */
    public function getRequestVersion(): float
    {
        if (Config::get('application.http.router.versionSource') === 'header') {
            $versionNumber = $this->request->getHeader(Config::get('application.http.router.versionName'));
        } elseif (Config::get('application.http.router.versionSource') === 'params') {
            $versionNumber = $this->request->getGet(Config::get('application.http.router.versionName'));
        }
        if (empty($versionNumber)) {
            return -1;
        }
        return (float)$versionNumber;
    }


    /**
     * 获取方法名称
     * @return string
     */
    public function getMethodName(): string
    {
        return $this->routeMapper['method'];
    }

    /**
     * 获取预定义路由参数名
     * @return array|mixed
     */
    public function getRouteParams()
    {
        if (empty($this->routeMapper['params'])) {
            return [];
        }
        $pathInfo = $this->request->getPathInfo();
        $paramString = substr($pathInfo, strlen($this->routeMapper['alias']));
        $paramArray = explode('/', $paramString);
        array_shift($paramArray);
        $params = [];
        foreach ($this->routeMapper['params'] as $key => $item) {
            $params[$item] = $paramArray[$key];
        }
        return $params;
    }

}
